/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the GLQuake source code.

 The GLQuake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The GLQuake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the GLQuake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// cvarSystem.h - framework used by dynamic-link libraries
//


#ifndef __FRAMEWORK_CVARSYSTEM_H__
#define __FRAMEWORK_CVARSYSTEM_H__


/*
 ==============================================================================

 Console Variables:

 CVars are used to hold boolean, numeric, or string variables that can be
 changed or displayed at the console as well as accessed directly in the code.

 CVars are mostly used to hold settings that can be changed from the console or
 saved to and loaded from config files, but are also occasionally used to
 communicate information between different modules of the program.

 The user can access CVars from the console in three ways:

    cvar                Prints the current value
    cvar X			    Sets the current value to X
    set cvar X		    Same as above, but creates the CVar if not present

 CVars may be declared multiple times using the same name. However, they will
 all reference the same value and changing the value of one CVar changes the
 value of all CVars with the same name.

 CVars are automatically range checked based on their type and any min/max
 specified.

 ==============================================================================
*/

enum cvarType_t {
	CVAR_BOOL,
	CVAR_INTEGER,
	CVAR_FLOAT,
	CVAR_STRING
};

enum cvarFlags_t {
	CVAR_ARCHIVE					= BIT(0),	// Saved to a config file
	CVAR_USERINFO					= BIT(1),	// Sent from client to server
	CVAR_SERVERINFO					= BIT(2),	// Sent from server to clients
	CVAR_NETWORKSYNC				= BIT(3),	// Sync'ed from server to clients
	CVAR_INIT						= BIT(4),	// Can only be set from the command line
	CVAR_READONLY					= BIT(5),	// Cannot be set by the user at all
	CVAR_CHEAT						= BIT(6),	// Cannot be set when cheats are disabled
	CVAR_LATCH						= BIT(7),	// Not changed until a subsystem restart
	CVAR_USERCREATED				= BIT(8),	// Created by the user with a "set" command
	CVAR_GAME						= BIT(9)	// Game variable
};

struct cvar_t {
	const char *			name;
	const char *			value;				// Current value
	const char *			resetValue;			// Initial value
	const char *			latchedValue;		// Latched value
	int						integerValue;		// Value converted to integer
	float					floatValue;			// Value converted to float

	cvarType_t				type;
	int						flags;
	const char *			description;
	float					min;
	float					max;

	bool					modified;			// Set each time the variable is changed

	cvar_t *				next;
	cvar_t *				nextHash;
};

// Functions exported by the engine
struct glqCVarSystem_t {
	// Creates the variable if it doesn't exist, or returns the existing one.
	// If the variable exists, the flags will be OR'ed in.
	// The description parameter can be NULL if you don't want it.
	cvar_t *				(*Register)(const char *name, const char *value, cvarType_t type, int flags, const char *description, float min, float max);

	// Sets the value of a variable
	void					(*SetBool)(cvar_t *cvar, bool value);
	void					(*SetInteger)(cvar_t *cvar, int value);
	void					(*SetFloat)(cvar_t *cvar, float value);
	void					(*SetString)(cvar_t *cvar, const char *value);

	// Updates a latched variable
	void					(*UpdateLatched)(cvar_t *cvar);

	// Finds a variable with the given name. Returns NULL if not found.
	cvar_t *				(*FindVariable)(const char *name);

	// Gets the value of a variable by name. Returns false, zero, or an empty
	// string if it doesn't exist.
	bool					(*GetVariableBool)(const char *name);
	int						(*GetVariableInteger)(const char *name);
	float					(*GetVariableFloat)(const char *name);
	const char *			(*GetVariableString)(const char *name);

	// Sets the value of a variable by name. Creates the variable if it doesn't
	// exist.
	void					(*SetVariableBool)(const char *name, bool value, bool force);
	void					(*SetVariableInteger)(const char *name, int value, bool force);
	void					(*SetVariableFloat)(const char *name, float value, bool force);
	void					(*SetVariableString)(const char *name, const char *value, bool force);
	
	// Returns true if cheats are allowed
	bool					(*AllowCheats)();

	// Gets flags that tell what kind of variables have been modified
	int						(*GetModifiedFlags)();

	// Sets flags that tell what kind of variables have been modified
	void					(*SetModifiedFlags)(int flags);

	// Clears flags to allow detecting another modification to variables
	void					(*ClearModifiedFlags)(int flags);

	// Returns an info string containing all the variables with any of the
	// given flags set
	const char *			(*InfoString)(int flags);
};


#endif	// __FRAMEWORK_CVARSYSTEM_H__